import { defineComponent, ref } from "vue"
import { createImgUrl, formatTime } from "@/utils/utils"

import ccLink from "./Link.vue"

import ccSpan from "./Span.vue"
import ccImage from "./Image.vue"
import ccTag from "./Tag.vue"
import ccSwitch from "./Switch.vue"
import ccTips from "./Tips.vue"

export default defineComponent({
  components: {
    ccLink,
    ccSwitch,
    ccImage,
    ccTag,
    ccTips,
    ccSpan
  },
  emits: ["select", "operation", "opselect", "change"],
  props: {
    tableJson: {
      type: Array,
      default: () => []
    },
    operation: {
      type: Array,
      default: () => []
    },
    needSelection: {
      type: Boolean,
      default: false
    },
    needIndex: {
      type: Boolean,
      default: false
    },
    needPagination: {
      type: Boolean,
      default: true
    },
    loading: {
      type: Boolean,
      default: false
    },
    data: {
      type: Array,
      default: () => []
    },
    total: {
      type: Number,
      default: 0
    },
    width: {
      type: String,
      default: "200"
    },
    opwidth: {
      type: String,
      default: "200"
    },
    maxHeight: {
      type: String,
      default: "540"
    },

    countWidth: {
      type: String,
      default: "60"
    },
    tipColor: {
      type: String,
      default: "blue"
    }
  },
  setup(props, cxt) {
    const emit = cxt.emit
    const pageSize = ref(10)
    const currentPage = ref(1)
    const formatSpanFn = (val: any) => {
      return val && val !== 0 ? val : "--"
    }
    const switchChange = (e: boolean) => {
      console.log(e)
    }
    const handleSelect = (selection: number) => {
      emit("select", selection)
    }
    const handleSizeChange = (val: number) => {
      pageSize.value = val
      sizeOrPageChange()
    }
    const handleCurrentChange = (val: number) => {
      currentPage.value = val
      sizeOrPageChange()
    }
    const sizeOrPageChange = () => {
      const obj = {
        pageSize: pageSize.value,
        pageNum: currentPage.value
      }
      emit("change", obj)
    }
    const handleOperation = (type: string, row: number, index: number) => {
      emit("operation", { type, row, index })
    }
    const createComponent = (row: any, item: any) => {
      const { type, filed, style, tips } = item
      let displayComponent = null
      let formatFn: Function = item.formatFn || ((e: any) => e)
      switch (type) {
        case "span":
          formatFn = item.formatFn || formatSpanFn
          displayComponent = (
            <ccSpan title={row[filed]} style={style}>
              {formatFn(row[filed], row)}
            </ccSpan>
          )
          break
        case "time":
          displayComponent = (
            <ccSpan title={row[filed]} style={style}>
              {formatTime(row[filed], item.timeFormat)}
            </ccSpan>
          )
          break
        case "link": {
          const router = item.router(row)
          // 当链接字段的值为空时，使用span标签展示内容
          displayComponent = (
            <ccLink style={style} router={router}>
              {formatFn(row[filed], row)}
            </ccLink>
          )
          break
        }
        case "switch": {
          // 当链接字段的值为空时，使用span标签展示内容
          displayComponent = (
            <ccSwitch value={row[filed] == 1} style={style} switchChange={switchChange}>
              {formatFn(row[filed], row)}
            </ccSwitch>
          )
          break
        }
        case "image": {
          formatFn = item.formatFn || createImgUrl
          const imgSrc = formatFn(row[filed], row)
          const previewSrcList = item.needPreviewImg ? [formatFn(row[item.previewFiled] || row[filed])] : []
          displayComponent = <ccImage preview-src-list={previewSrcList} style={style} src={imgSrc} />
          break
        }
        case "tag": {
          const colorList = item.colorList
          const colorStyle = (typeof colorList === "function" ? colorList(row) : colorList[row[filed]]) || {}
          displayComponent = <ccTag myStyle={{ ...colorStyle }}>{formatFn(row[filed], row)}</ccTag>
          break
        }
        case "tip": {
          const colorList = item.colorList
          const colorStyle = typeof colorList === "function" ? colorList(row) : colorList[row[filed]]
          const tipcontents = row[tips].split(",")
          displayComponent =
            tipcontents.length < 2 ? (
              <ccTag myStyle={{ ...colorStyle, ...style }}>{formatFn(row[filed], row)}</ccTag>
            ) : (
              <el-popover placement="top-start" trigger="hover">
                {formatFn(row[filed], row, true)}
                <div class="name-wrapper">
                  <ccTag style={{ ...colorStyle, ...style }}>{formatFn(row[filed], row)}</ccTag>
                </div>
              </el-popover>
            )
          break
        }
        default:
          break
      }
      return displayComponent
    }

    return () => {
      const {
        tableJson,
        data,
        operation,
        needSelection,
        needIndex,
        needPagination,
        maxHeight,
        countWidth,
        opwidth,
        total,
        tipColor
      } = props
      // 表格选择框
      const selectTableItem = <el-table-column reserve-selection type="selection" width="55"></el-table-column>

      const sequenceTableItem = (
        <el-table-column
          label="序号"
          type="index"
          index={(index: number) => index + 1 + (currentPage.value - 1) * pageSize.value}
          width={countWidth}
        ></el-table-column>
      )
      // 列表显示项
      const commonTableItem = tableJson?.map((item: any, index) => {
        const tableprops = {
          prop: item.filed,
          key: index,
          align: item.align,
          label: item.label,
          width: item.staticWidth,
          minWidth: item.width
        }
        let { renderFn, hide } = item
        renderFn = typeof renderFn == "function" ? renderFn.bind(this) : null
        return (
          <el-table-column
            {...tableprops}
            v-slots={{
              default: (scope: any) =>
                (renderFn && renderFn(scope.row, scope.$index)) || createComponent(scope.row, item)
            }}
          ></el-table-column>
        )
      })
      const operationTableItem =
        operation?.length && Number(opwidth) ? (
          <el-table-column
            fixed="right"
            label="操作"
            width={opwidth}
            v-slots={{
              default: (scope: any) => {
                return operation
                  .map((action: any, index) => {
                    return action.hide && action.hide(scope.row, scope.$index) ? null : action.isDrop ? (
                      <el-dropdown
                        style={{ marginLeft: "10px" }}
                        on-command={(type: string) => handleOperation(type, scope.row, scope.$index)}
                      >
                        <span class="el-dropdown-link" style={{ fontSize: "14px" }}>
                          {action.name}
                          <i class="el-icon-arrow-down el-icon--right"></i>
                        </span>
                        <el-dropdown-menu slot="dropdown">
                          {action.children.map((el: any) => {
                            return el.hide && el.hide(scope.row) ? null : (
                              <el-dropdown-item disabled={el.disabled && el.disabled(scope.row)} command={el.type}>
                                {el.name}
                              </el-dropdown-item>
                            )
                          })}
                        </el-dropdown-menu>
                      </el-dropdown>
                    ) : (
                      <el-button
                        disabled={action.disabled && action.disabled(scope.row)}
                        class="table-btn"
                        size="mini"
                        type="text"
                        onClick={() => handleOperation(action.type, scope.row, scope.$index)}
                        key={index}
                      >
                        <span style={{ color: action.color, fontSize: "14px" }}>{action.name}</span>
                      </el-button>
                    )
                  })
                  .filter(Boolean)
              }
            }}
          ></el-table-column>
        ) : null
      const pagination = () => {
        let sel_props = {
          on: {
            change: () => {
              console.log("val")
            },
            "size-change": (val: number) => {
              console.log(111)

              console.log(val)
            },
            "current-change": (val: number) => {
              console.log(222)
              console.log(val)

              handleCurrentChange(val)
            }
          }
        }
        return (
          <div style="display: flex;justify-content: right;text-align: right; margin: 16px 0 16px 24px; margin-bottom: 0px;">
            <el-pagination
              {...sel_props}
              background
              onSizeChange={handleSizeChange}
              onCurrentChange={handleCurrentChange}
              v-model:current-page={currentPage.value}
              page-sizes={[10, 25, 50, 80]}
              v-model:page-size={pageSize.value}
              layout="total, sizes, prev, pager, next, jumper"
              total={total}
            ></el-pagination>
          </div>
        )
      }
      //  总数小于单页数
      const haspage = !total || pageSize.value / total < 1

      // 分页组件
      return (
        <div
          class="common-table fullscreen__loading"
          v-loading={props.loading}
          element-loading-spinner="el-icon-loading"
          element-loading-background="rgba(0, 0, 0, 0.4)"
        >
          <el-table
            header-row-class-name="table-header"
            size="large"
            highlight-current-row
            on-selection-change={handleSelect}
            {...props}
            data={data}
          >
            {needSelection ? selectTableItem : null}
            {needIndex ? sequenceTableItem : null}
            {commonTableItem}
            {operation?.length ? operationTableItem : null}
          </el-table>
          {data?.length && haspage && needPagination ? pagination() : null}
        </div>
      )
    }
  }
})
